A typical problem faced by software developers is figuring out why their application program behaves inconsistently depending on how and where it runs. For example, the application in question may run fine on Windows 2000™ but may encounter heap corruption on Windows XP™. Or the application in question may run more slowly after a particular sequence of user activity. Or a menu item may mysteriously fail to get displayed if a seemingly unrelated setting or option is specified. These are but a few examples of various maladies that may plague a software application, either during development or in the field.
Traditionally, in order to address these issues, the software developer may reproduce the unexpected scenario while using a debugger. This may require the software developer to select one or more breakpoints at which the developer hopes to find clues about the misbehaving application. Unfortunately, given today's complex systems, selecting these breakpoints may prove challenging.
Further, sometimes two instances of the debugger are needed (running side by side) to step through a suspicious code sequence. Again, this methodology requires the selection of one or more breakpoints. The developer can use one instance of the debugger to step through the badly behaving instance of the program, while also using the other instance of the debugger for simultaneously stepping through the equivalent code sequence on a more properly behaving instance of the program. This practice allows the developer to explore the conditions that cause the behavior of the program to become different, for the two instances of the program. Unfortunately, this requires the developer to keep track of which run is associated with which debugger. It also requires the program's behavior to be deterministically repeatable, for both instances of the program, from one run to the next, because often during debugging the developer will “step past” the point where an unexpected event happens and must restart the two instances of the program under the two instances of the debugger to explore the causes of that unexpected event. Unfortunately, many complex programs do not always behave deterministically.